Improve test output
authorYehuda Katz <wycats@gmail.com>
Mon, 21 Jul 2014 19:23:01 +0000 (12:23 -0700)
committerYehuda Katz <wycats@gmail.com>
Mon, 21 Jul 2014 19:23:01 +0000 (12:23 -0700)
libs/hammer.rs
libs/toml-rs
src/bin/cargo-test.rs
src/cargo/ops/cargo_rustc/mod.rs
tests/support/mod.rs
tests/test_cargo_test.rs

index 3e6218afdc17dcdd456f7ad2be38e2fbba493983..c085c639ac06909301707721b174e83f40bbac70 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 3e6218afdc17dcdd456f7ad2be38e2fbba493983
+Subproject commit c085c639ac06909301707721b174e83f40bbac70
index 76cf3d1d3ef0fb21ade21d313d8b67b65ed7e8ac..a3c7f2c38ef795ad34e225ca54fa6bf625e8a842 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 76cf3d1d3ef0fb21ade21d313d8b67b65ed7e8ac
+Subproject commit a3c7f2c38ef795ad34e225ca54fa6bf625e8a842
index eb9dfeaf9c84479f19806c37208e68884f7d4fbc..707681ae6831c3a9fa11d63d00eb9573b13e393d 100644 (file)
@@ -14,7 +14,7 @@ use cargo::ops;
 use cargo::{execute_main_without_stdin};
 use cargo::core::{MultiShell};
 use cargo::util;
-use cargo::util::{CliResult, CliError, CargoError};
+use cargo::util::{CliResult, CliError, human};
 use cargo::util::important_paths::find_project_manifest;
 
 #[deriving(PartialEq,Clone,Decodable)]
@@ -62,9 +62,7 @@ fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
     for file in test_executables.iter() {
         try!(util::process(test_dir.join(file.as_slice()))
                   .args(options.rest.as_slice())
-                  .exec().map_err(|e| {
-            CliError::from_boxed(e.box_error(), 1)
-        }));
+                  .exec().map_err(|_| CliError::from_boxed(human(""), 1)));
     }
 
     Ok(None)
index 16c0976f5f86ed1ff307f26e424e398c931d47cb..8cd128201356c69f06cdcefcc370691edb658f14 100644 (file)
@@ -196,7 +196,8 @@ fn rustc(package: &Package, target: &Target,
             } else {
                 log!(5, "executing deps");
                 try!(rustc.exec_with_output().and(Ok(())).map_err(|err| {
-                    caused_human(format!("Could not compile `{}`.\n{}", name, err.output().unwrap()), err)
+                    caused_human(format!("Could not compile `{}`.\n{}",
+                                         name, err.output().unwrap()), err)
                 }))
             }
             Ok(Vec::new())
index 25cf7203e09e7dfd9b5b44753f8386265d0af9f6..62054c3aabb45d12e94dbe2ed7c045dd8d6c9b31 100644 (file)
@@ -296,13 +296,38 @@ impl Execs {
                     Some(actual) => {
                         // Let's not deal with \r\n vs \n on windows...
                         let actual = actual.replace("\r", "");
+                        let actual = actual.replace("\t", "<tab>");
+
+                        let a = actual.as_slice().lines();
+                        let e = out.lines();
+
+                        let diffs = zip_all(a, e).enumerate();
+                        let mut diffs = diffs.filter_map(|(i, (a,e))| {
+                            match (a, e) {
+                                (Some(a), Some(e)) => {
+                                    if e.as_slice().equiv(&a.as_slice()) {
+                                        None
+                                    } else {
+                                        Some(format!("{:3} - |{}|\n    + |{}|\n", i, e, a))
+                                    }
+                                },
+                                (Some(a), None) => {
+                                    Some(format!("{:3} -\n    + |{}|\n", i, a))
+                                },
+                                (None, Some(e)) => {
+                                    Some(format!("{:3} - |{}|\n    +\n", i, e))
+                                },
+                                (None, None) => fail!("Cannot get here")
+                            }
+                        });
+
+                        let diffs = diffs.collect::<Vec<String>>().connect("\n");
+
                         ham::expect(actual.as_slice() == out,
-                                    format!("{} was:\n\
-                                            `{}`\n\n\
-                                            expected:\n\
-                                            `{}`\n\n\
+                                    format!("differences:\n\
+                                            {}\n\n\
                                             other output:\n\
-                                            `{}`", description, actual, out,
+                                            `{}`", diffs,
                                             String::from_utf8_lossy(extra)))
                     }
                 }
@@ -311,6 +336,30 @@ impl Execs {
     }
 }
 
+struct ZipAll<T, I1, I2> {
+    first: I1,
+    second: I2,
+}
+
+impl<T, I1: Iterator<T>, I2: Iterator<T>> Iterator<(Option<T>, Option<T>)> for ZipAll<T, I1, I2> {
+    fn next(&mut self) -> Option<(Option<T>, Option<T>)> {
+        let first = self.first.next();
+        let second = self.second.next();
+
+        match (first, second) {
+            (None, None) => None,
+            (a, b) => Some((a, b))
+        }
+    }
+}
+
+fn zip_all<T, I1: Iterator<T>, I2: Iterator<T>>(a: I1, b: I2) -> ZipAll<T, I1, I2> {
+    ZipAll {
+        first: a,
+        second: b
+    }
+}
+
 impl ham::SelfDescribing for Execs {
     fn describe(&self) -> String {
         "execs".to_string()
index edb30052a7d0fcb19f0add0e5311a0c0503c0ad8..ff9bdfe9d188101a13e81124b12fecdc7823cf2b 100644 (file)
@@ -35,7 +35,47 @@ test!(cargo_test_simple {
         execs().with_stdout(format!("{} foo v0.5.0 (file:{})\n\n\
                                     running 1 test\n\
                                     test test_hello ... ok\n\n\
-                                    test result: ok. 1 passed; 0 failed; \
+                                    test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured\n\n",
+                                    COMPILING, p.root().display())));
+
+    assert_that(&p.bin("test/foo"), existing_file());
+})
+
+test!(cargo_test_failing_test {
+    let p = project("foo")
+        .file("Cargo.toml", basic_bin_manifest("foo").as_slice())
+        .file("src/foo.rs", r#"
+            fn hello() -> &'static str {
+                "hello"
+            }
+
+            pub fn main() {
+                println!("{}", hello())
+            }
+
+            #[test]
+            fn test_hello() {
+                assert_eq!(hello(), "nope")
+            }"#);
+
+    assert_that(p.cargo_process("cargo-build"), execs());
+    assert_that(&p.bin("foo"), existing_file());
+
+    assert_that(
+        process(p.bin("foo")),
+        execs().with_stdout("hello\n"));
+
+    assert_that(p.process(cargo_dir().join("cargo-test")),
+        execs().with_stdout(format!("{} foo v0.5.0 (file:{})\n\n\
+                                    running 1 test\n\
+                                    test test_hello ... FAILED\n\n\
+                                    failures:\n\n\
+                                    ---- test_hello stdout ----\n<tab>\
+                                    task 'test_hello' failed at 'assertion failed: \
+                                    `(left == right) && (right == left)` (left: \
+                                    `hello`, right: `nope`)', src/foo.rs:12\n<tab>\n<tab>\n\n\
+                                    failures:\n    test_hello\n\n\
+                                    test result: FAILED. 0 passed; 1 failed; \
                                     0 ignored; 0 measured\n\n",
                                     COMPILING, p.root().display())));
 
@@ -85,7 +125,6 @@ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured";
     let head = format!("{compiling} foo v0.0.1 (file:{dir})",
                        compiling = COMPILING, dir = p.root().display());
 
-    println!("{}", out);
     assert!(out == format!("{}\n\n{}\n\n\n{}\n\n", head, bin, lib).as_slice() ||
             out == format!("{}\n\n{}\n\n\n{}\n\n", head, lib, bin).as_slice());
 })